package titt.service.content;

import titt.head.HTTPHead;
import titt.head.HeadFactory;
import titt.head.request.Content;
import titt.head.response.ResponseHead;
import titt.io.IOFactory;
import titt.io.socket.in.TITTInputStream;
import titt.io.socket.out.TITTOutputStream;
import titt.io.util.wrap.AutoWrapper;
import titt.util.io.pipe.PipeListener;
import titt.util.io.pipe.StreamPiper;

public class NuderResponse {
	
	private final ResponseHead resp;
	private final int length;
	
	private Object content;
	private TITTInputStream in;
	
	private PipeListener listener;
	
	public NuderResponse(Object content) {
		this(content, 200);
	}
	
	public NuderResponse(Object content, int status) {
		this(content, status, AutoWrapper.get().getMimeType(content));
	}
	
	public NuderResponse(Object content, String contentType) {
		this(content, 200, contentType);
	}
	
	public NuderResponse(Object content, int status, String contentType) {
		this(content, status, contentType, HeadFactory.EMPTY);
	}
	
	public NuderResponse(Object content, int status, String contentType, HTTPHead head) {
		Content c = new Content(AutoWrapper.get().getLength(content), contentType, head);
		this.resp = new ResponseHead(status, c);
		this.length = c.getContentLength();
		this.content = content;
	}

	
	public NuderResponse(ResponseHead resp, TITTInputStream in) {
		Content c = new Content(resp);
		this.resp = resp;
		this.in = in;
		this.content = in;
		this.length = c.containsContentLength()? c.getContentLength() : -1;
	}
	

	public void setPipeListener(int minInterval, PipeListener listener) {
		this.listener = new AsyncListener(minInterval, listener);
	}
	
	public void setPipeListener(PipeListener listener) {
		this.listener = new AsyncListener(listener);
	}
	
	public void writeTo(TITTOutputStream out) throws Exception {
		if(in == null) {
			AutoWrapper.get().writeTo(listener, out, content);
		}
		else {
			StreamPiper p = IOFactory.createStreamPiper();
			p.pipe(in, out, getLength(), listener);
		}
	}

	public ResponseHead getHead() {
		return resp;
	}
		
	public TITTInputStream getStream() {
		return in;
	}
	
	public int getLength() {
		return length;
	}

	@SuppressWarnings("unchecked")
	public <T> T getContent() {
		return (T)content;
	}
}
